<?php
/*
  [EWEISHOP] Copyright(C) 2017 Elinkint Inc.
  This is NOT a freeware, use is subject to license terms
   
  MiniProgramAppCode.php 2018-05-25 15:01 cunx $
   
*/

namespace common\library\wechat\miniprogram;

use common\component\wechat\Wechat;
use common\helpers\Error;
use common\helpers\File;
use common\library\wechat\WechatApi;
use EasyWeChat\Kernel\Http\StreamResponse;

/**
 * 生成小程序码和小程序二维码
 * Class MiniProgramAppCode
 * @package common\library\wechat\miniprogram
 * @author cunx
 */
class MiniProgramAppCode extends WechatApi
{

    static $apiType = 'miniProgram';

    /**
     * 获取小程序码
     * 接口A: 适用于需要的码数量较少的业务场景
     * -----------------------
     * 通过该接口生成的小程序码，永久有效
     * 数量限制见文末说明，请谨慎使用。
     * 用户扫描该码进入小程序后，将直接进入 path 对应的页面。
     * -----------------------
     * @param string $path                  扫描小程序码后访问的路径
     * @param array $optional
     * @param array $optional[width]        二维码的宽度，默认 430
     * @param array $optional[auto_color]   默认false ，自动配置线条颜色，如果颜色依然是黑色，则说明不建议配置主色调
     * @param array $optional[line_color]   auto_color 为 false 时生效，使用 rgb 设置颜色 例如 {"r":"xxx","g":"xxx","b":"xxx"},十进制表示
     * @param array $optional[is_hyaline]   默认false ，是否需要透明底色， is_hyaline 为true时，生成透明底色的小程序码
     *
     * @param array $optional[directory]    二维码存储目录，不传则不保存
     * @param array $optional[fileName]     二维码存储文件名，不传则由系统自动命名
     * @return array|bool|void|StreamResponse
     * @author cunx
     * @link    @link https://developers.weixin.qq.com/miniprogram/dev/api/qrcode.html 获取二维码文档：接口A
     */
    public static function get(string $path, array $optional = []){
        return self::getCode('get', $path, $optional);
    }

    /**
     * 获取小程序码
     * 接口B：适用于需要的码数量极多的业务场景
     *--------------------------------------
     * 通过该接口生成的小程序码，永久有效，数量暂无限制。
     * 用户扫描该码进入小程序后，开发者需在对应页面获取的码中 scene 字段的值，再做处理逻辑。
     * -------------------------------------
     * @param string $scene                 最大32个可见字符，只支持数字，大小写英文以及部分特殊字符：!#$&'()*+,/:;=?@-._~，
     *                                      其它字符请自行编码为合法字符（因不支持%，中文无法使用 urlencode 处理，请使用其他编码方式）
     * @param array $optional
     * @param array $optional[page]         必须是已经发布的小程序存在的页面（否则报错），例如 "pages/index/index" ,
     *                                      根路径前不要填加'/',不能携带参数（参数请放在scene字段里），如果不填写这个字段，默认跳主页面
     * @param array $optional[width]        二维码的宽度，默认 430
     * @param array $optional[auto_color]   默认false ，自动配置线条颜色，如果颜色依然是黑色，则说明不建议配置主色调
     * @param array $optional[line_color]   auto_color 为 false 时生效，使用 rgb 设置颜色 例如 {"r":"xxx","g":"xxx","b":"xxx"},十进制表示
     * @param array $optional[is_hyaline]   默认false ，是否需要透明底色， is_hyaline 为true时，生成透明底色的小程序码
     *
     * @param array $optional[directory]    二维码存储目录，不传则不保存
     * @param array $optional[fileName]     二维码存储文件名，不传则由系统自动命名
     * @return array|bool|void|StreamResponse
     * @author cunx
     * @link https://developers.weixin.qq.com/miniprogram/dev/api/qrcode.html 获取二维码文档：接口B
     */
    public static function getUnlimit(string $scene, array $optional = []){
        return self::getCode('getUnlimit', $scene, $optional);
    }


    /**
     * 获取小程序二维码
     * 接口C：适用于需要的码数量较少的业务场景
     * @param string $path                小程序页面路径
     * @param string $directory
     * @param string $fileName
     * @param array $optional             可选项数组
     * @param array $optional[width]        二维码的宽度
     * @param array $optional[directory]    二维码存储目录，不传则不保存
     * @param array $optional[fileName]     二维码存储文件名，不传则由系统自动命名
     * @return array|bool|void|StreamResponse
     * @author cunx
     * @link    @link https://developers.weixin.qq.com/miniprogram/dev/api/qrcode.html 获取二维码文档：接口C
     */
    public static function getQrCode(string $path, array $optional = []){
        return self::getCode('getQrCode', $path, $optional);
    }

    /**
     * 通用小程序二维码 or 小程序码
     * @param string $func
     * @param string $scene_or_path
     * @param array $optional
     * @return array|bool|void|StreamResponse
     * @author cunx
     */
    private static function getCode(string $func, string $scene_or_path, array $optional = []){
        $func === 'getQrCode' && ( $width = $optional['width'] );
        $directory = $optional['directory'];
        unset($optional['directory']);
        $fileName = $optional['fileName'];
        unset($optional['fileName']);
        $response = self::getInstance()->app_code->$func($scene_or_path, $func === 'getQrCode'? $width : $optional);
        if ($directory && $response instanceof StreamResponse){
            $response->saveAs($directory,$fileName??'');
        }
        return Wechat::apiError($response);
    }

    /**
     * 保存小程序码到指定目录
     * @param StreamResponse $response  通过A/B/C只读接口获得的StreamResponse
     * @param string $directory         指定存储目录
     * @param string $fileName          指定文件名称，不填写则系统自动命名
     * @return bool
     * @author cunx
     */
    public static function saveAsFile(StreamResponse $response, string $directory, string $fileName = ''){
        try{
            $response->saveAs($directory, $fileName);
        }catch(\Exception $response){
            return false;
        }
        return true;
    }

}